<template>
  <div class="monaco-container">
    <div v-if="loading" class="loading">编译器初始化中...</div>
    <div v-show="!loading" ref="editorContainer" class="monaco-editor-container"></div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import { useDebounceFn } from '@vueuse/core'
import { jsonSnippets, ftlSnippets } from '/public/monaco/snippets'
import loader from '@monaco-editor/loader'

// ================ 基础配置 ================
const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  language: {
    type: String,
    default: 'json'
  },
  theme: {
    type: String,
    default: 'vs-dark'
  },
  minimap: {
    type: Boolean,
    default: true
  }
})
const emit = defineEmits(['update:modelValue', 'save'])
const editorContainer = ref(null)
const loading = ref(true)
let editor = null
let monaco = null

// CDN 配置
const baseVs = process.env.NODE_ENV === 'production' ? `${location.origin}/${location.pathname.split('/')[1]}/monaco/min/vs` : `${location.origin}/monaco/min/vs`
const baseUrl = process.env.NODE_ENV === 'production' ? `${location.origin}/${location.pathname.split('/')[1]}/monaco/min/` : `${location.origin}/monaco/min/`
loader.config({
  paths: {
    vs: baseVs
  },
  'vs/nls': { availableLanguages: { '*': 'zh-cn' } }
})

// 配置 workers 路径
window.MonacoEnvironment = {
  getWorkerUrl: function () {
    // 确保先加载 loader.js
    const getWorkerPath = () => {
      return `data:text/javascript;charset=utf-8,${encodeURIComponent(`
        self.MonacoEnvironment = {
          baseUrl: '${baseUrl}'
        };
        importScripts('${baseUrl}vs/base/worker/workerMain.js');
      `)}`
    }

    return getWorkerPath()
  }
}
// ================ 语言特性配置 ================
// 语言特性配置
const configureLanguageFeatures = monaco => {
  // 添加自定义代码片段
  monaco.languages.registerCompletionItemProvider('json', {
    provideCompletionItems: () => {
      const suggestions = jsonSnippets.map(snippet => ({
        label: snippet.label,
        kind: monaco.languages.CompletionItemKind.Snippet,
        insertText: snippet.insertText,
        insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
        documentation: snippet.documentation
      }))
      return { suggestions }
    }
  })
  monaco.languages.registerCompletionItemProvider('freemarker2', {
    provideCompletionItems: () => {
      const suggestions = ftlSnippets.map(snippet => ({
        label: snippet.label,
        kind: monaco.languages.CompletionItemKind.Snippet,
        insertText: snippet.insertText,
        insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
        documentation: snippet.documentation
      }))
      return { suggestions }
    }
  })
}
// ================ 编辑器功能增强 ================
// 编辑器配置和菜单本地化
const configureEditor = monaco => {
  // 保存文档动作
  editor.addAction({
    id: 'save-document',
    label: '保存文档',
    keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS],
    run: () => emit('save')
  })
}

// ================ 生命周期和事件处理 ================
// 编辑器初始化
onMounted(async () => {
  try {
    monaco = await loader.init()

    // 配置编辑器特性
    configureLanguageFeatures(monaco)

    editor = monaco.editor.create(editorContainer.value, {
      value: props.modelValue,
      language: props.language,
      theme: props.theme || 'vs-dark',
      automaticLayout: true,
      fontSize: 14,
      lineNumbers: 'on',
      roundedSelection: false,
      scrollBeyondLastLine: false,
      readOnly: false,
      minimap: {
        enabled: props.minimap
      },
      formatOnPaste: true,
      formatOnType: true,
      tabSize: 2,
      autoIndent: 'full',
      snippetSuggestions: 'top',
      suggestOnTriggerCharacters: true,
      wordBasedSuggestions: true,
      parameterHints: { enabled: true },
      quickSuggestions: {
        other: true,
        comments: true,
        strings: true
      },
      contextmenu: true,
      links: true,
      mouseWheelZoom: true,
      folding: true,
      renderWhitespace: 'selection',
      // 添加更多格式化选项
      formatOnSave: true,
      formatOptions: {
        tabSize: 2,
        insertSpaces: true,
        trimTrailingWhitespace: true,
        insertFinalNewline: true
      }
    })

    configureEditor(monaco)

    // 添加内容变化监听器
    editor.onDidChangeModelContent(() => {
      debouncedUpdate(editor.getValue())
    })

    loading.value = false
  } catch (error) {
    console.error('Failed to load Monaco Editor:', error)
    loading.value = false
  }
})

// 资源清理
const disposeResources = () => {
  if (editor) {
    editor.getModel()?.dispose()
    editor.dispose()
    editor = null
  }
  monaco = null
}

onBeforeUnmount(() => {
  disposeResources()
})

// ================ 响应式处理 ================
// 语言监听
watch(
  () => props.language,
  newLanguage => {
    if (editor && monaco) {
      monaco.editor.setModelLanguage(editor.getModel(), newLanguage)
    }
  }
)

// 内容监听
watch(
  () => props.modelValue,
  newValue => {
    if (editor && newValue !== editor.getValue()) {
      editor.setValue(newValue)
    }
  }
)

// 内容更新防抖
const debouncedUpdate = useDebounceFn(value => {
  emit('update:modelValue', value)
}, 300)
</script>

<style scoped>
.monaco-container {
  padding-top: 10px;
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  position: relative;
  display: flex;
  flex-direction: column;
}

.monaco-editor-container {
  flex: 1;
  overflow: hidden;
}

.loading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #666;
}
</style>
